<?php
declare (strict_types=1);

namespace addons\V2\admin\model;

use addons\Pay\facade\Pay;
use addons\Target\facade\Target;
use app\common\model\Address;
use app\common\model\Config;
use app\common\model\Relation;
use app\common\model\UserRelease;
use think\facade\Cache;
use think\facade\Db;
use think\facade\Event;

class OrderTemporary extends Order
{

    /**
     * @param $param
     * @param $user
     * @return array
     * 原点 2023年1月3日09:52:42 设置临时下单商品
     */
    public static function setTemporary($param, $user): array
    {
        try {
            if ($param['type'] == 1) {
                $result = ProductSpecValue::getSettled($param, $user);
                if ($result['code'] != 1) return $result;
                $productTemporary = $result['data'];
            } else {
                $result = ProductCart::getSettled($user, $param['cart_id']);
                if ($result['code'] != 1) return $result;
                $productTemporary = $result['data'];
            }
            if (empty($productTemporary)) {
                return ['code' => -1, 'msg' => '服务器错误，请稍后再试'];
            }
            //缓存购物车标识
            if (isset($param['cart_id']) && $param['cart_id']) {
                Cache::set('productTemporaryCartId_' . $user->id, $param['cart_id']);
            }
            Cache::set('productTemporary_' . $user->id, $productTemporary);
            return ['code' => 1, 'msg' => 'success'];
        } catch (\Exception $e) {
            return ['code' => -1, 'msg' => $e->getMessage()];
        }
    }

    /**
     * @param $uid -- 会员ID
     * @return array
     * 原点 2022年1月8日16:45:24 获得会员临时暂存的订单
     */
    public static function getTemporary($uid): array
    {
        try {
            $temporary = Cache::get('productTemporary_' . $uid);
            if (empty($temporary)) {
                return ['code' => -1, 'msg' => '加载失败，请再试一次！'];
            }
            $temporary['address'] = Address::getDefault($uid);
            return ['code' => 1, 'msg' => 'success', 'data' => $temporary];
        } catch (\Exception $e) {
            return ['code' => -1, 'msg' => '加载失败，请再试一次！'];
        }
    }

    public static function getPayment($id)
    {
        try {
            $info = parent::where('id', $id)->field('id,sn,real_amount,expire_time,freight,cash,integral,status,order_type,pay_method,pay_way')->find();
            if (empty($info)) {
                return ['code' => -1, 'msg' => '无效订单'];
            }
            if ($info->getData('status') != 1) {
                return ['code' => -1, 'msg' => '订单已支付或已失效'];
            }
            $data['order'] = $info;
            $data['method'] = self::payWay($info->order_type);

            return ['code' => 1, 'msg' => 'success', 'data' => $data];
        } catch (\Exception $e) {
            return ['code' => -1, 'msg' => $e->getMessage()];
        }
    }

    public static function payWay($cate_1 = ''): array
    {

        switch ($cate_1) {
            case 1:
                $method = self::getPaymentMethod('wechat');
                break;
            case 2:
                $method = self::getPaymentMethod('currency,wechat');
                break;
            case 3:
                $method = self::getPaymentMethod('bonus,wechat');
                break;
            default:
                $method = self::getPaymentMethod('wechat');
        }

        return $method;
    }

    public static function getPaymentMethod($value)
    {
        $method = [];
        foreach (explode(',', $value) as $item) {
            $method[] = [
                'title'           => get_pay_way($item),
                'pay_way'         => $item,
                'icon'            => '/static/api/img/' . $item . '.png',
                'is_pay_password' => in_array($item, ['alipay', 'wechat', 'behalf']) ? 0 : 1
            ];
        }
        return $method;
    }

    /**
     * @param $param
     * @param $user
     * @return array
     * 原点 2023年1月4日14:50:07 提交订单
     */
    public static function submit($param, $user): array
    {
        try {
            $temporary = Cache::get('productTemporary_' . $user->id);
            if (!$temporary) {
                return ['code' => -1, 'msg' => '您有未支付订单，如需更换支付方式，请重新下单'];
            }
            $address = '';
            if($temporary['type']==2)
            {
                if (!isset($param['address_id']) || !$param['address_id']) {
                    return ['code' => -1, 'msg' => '请选择收货地址'];
                }
                $address = Address::where('id', $param['address_id'])->find();
                if (empty($address)) {
                    return ['code' => -1, 'msg' => '收货地址错误，请重新选择'];
                }
            }

            $temporary['address_id'] = $param['address_id'];
            $temporary['remark'] = !empty($param['remark']) ? $param['remark'] : '';

            return self::createOrder($temporary, $user, $address);
        } catch (\Exception $e) {
            return ['code' => -1, 'msg' => $e->getMessage()];
        }
    }

    public static function createOrder($param, $user, $address)
    {
        //总运费
        $freightTotal = 0;
        $total = 0;
        $integral = 0;
        $cash = 0;
        $order_type = 0;
        $pay_method = 0;
        $type = 0;
        foreach ($param['product'] as &$children) {
            $product = Product::where(['id' => $children['pid'], 'status' => 1])
                ->field('id,title,freight,cate_1,stock,sales,integral,vip_price,cash,icon,spec_open,pay_method,type')->find();

            if (empty($product)) {
//                return ['code' => -1, 'msg' => '商品《' . $product->title . '》已下架'];
                return ['code' => -1, 'msg' => '商品已下架'];
            }
            if ($children['num'] <= 0) {
//                return ['code' => -1, 'msg' => '商品《' . $product->title . '》数量错误'];
                return ['code' => -1, 'msg' => '商品数量错误'];
            }
            if ($product->spec_open) {
                $specValue = ProductSpecValue::where('id', $children['spec_value_id'])->find();
                if (empty($specValue) || $children['num'] > $specValue->stock) {
                    return ['code' => -1, 'msg' => '商品《' . $product->title . '/ ' . $children['sku_name'] . '》库存不足'];
                }
                $children['vip_price'] = $specValue->vip_price;
                $children['icon'] = $specValue->icon;

                //减少库存
                $specValue->stock = $specValue->stock - $children['num'];
                $specValue->save();
            } else {
                if ($children['num'] > $product->stock) {
//                    return ['code' => -1, 'msg' => '商品《' . $product->title . '》库存不足'];
                    return ['code' => -1, 'msg' => '商品库存不足'];
                }
                $children['vip_price'] = $product->vip_price;
                $children['integral'] = $product->integral;
                $children['cash'] = $product->cash;
                $children['icon'] = $product->icon;
            }

            //完善订单商品信息
            $children['title'] = $product->title;

            //单个商品的总价格和总运费
            $productTotal = $children['vip_price'] * $children['num'];
            $productIntegral =  $children['integral'] * $children['num'];
            $productCash =  $children['cash'] * $children['num'];
            $productFreightTotal = $product->freight * $children['num'];

            //订单总价格，总运费累加
            $total += $productTotal;
            $integral += $productIntegral;
            $cash += $productCash;
            $freightTotal += $productFreightTotal;

            //增加销量
            $product->sales = $product->sales + $children['num'];
            $product->stock = $product->stock - $children['num'];
            $product->save();

            //定义订单类别
            $order_type = $product->cate_1;
            $pay_method = $product->pay_method;
            $type = $product->getData('type');
        }
        parent::startTrans();
        try {
            $new = parent::create([
                'sn'              => date('YmdHis') . $user->id . rand(100000, 999999),
                'uid'             => $user->id,
                'address_id'      => isset($param['address_id']) ? $param['address_id'] : 0,
                'expire_time'     => time() + 1800,
                'freight'         => $freightTotal,
                'receiver'        => !empty($address) ? $address->nickname : '',
                'receiver_tel'    => !empty($address) ? $address->tel : '',
                'province'        => !empty($address) ? $address->province : '',
                'city'            => !empty($address) ? $address->city : '',
                'district'        => !empty($address) ? $address->district : '',
                'address_details' => !empty($address) ? $address->details : '',
                'total_amount'    => $total + $freightTotal,
                'real_amount'     => $total + $freightTotal,
                'integral'        => $integral,
                'cash'            => $cash,
                'order_type'      => $order_type,
                'remark'          => $param['remark'],
                'pay_method'      => $pay_method,
                'type'            => $type
            ]);
            $walk = ['order_id' => $new->id, 'uid' => $user->id];
            array_walk($param['product'], function (&$value, $key, $walk) {
                $value = array_merge($value, $walk);
            }, $walk);
            (new OrderProduct())->insertAll($param['product']);

            $cart_id = Cache::get('productTemporaryCartId_' . $user->id);
            if ($cart_id) {
                ProductCart::destroy(['id' => $cart_id], true);
                Cache::delete('productTemporaryCartId_' . $user->id);
            }
            Cache::delete('productTemporary_' . $user->id);

            parent::commit();
            return ['code' => 1, 'msg' => 'success', 'data' => $new->id];
        } catch (\Exception $e) {
            parent::rollback();
            return ['code' => -1, 'msg' => $e->getMessage()];
        }

    }

    public static function payment($param, $user): array
    {
        try {
            $info = parent::where('id', $param['id'])->find();
            if ($info->getData('status') != 1) {
                return ['code' => -1, 'msg' => '订单已支付或已失效'];
            }
            $account = $param['pay_way'];
            $info->pay_way = $param['pay_way'];
            $info->save();
            switch ($account) {
                case "integral":
                    if (md5($param['pay_password']) != $user->pay_password) {
                        return ['code' => -1, 'msg' => '支付密码错误'];
                    }
                    if ($user->assets->$account < $info->integral) {
                        return ['code' => -1, 'msg' => '余额不足'];
                    }
                    return self::operations($info, $user, $account);
                case "wechat":
//                return ['code' => -1, 'msg' => '暂未开放'];
                    $notifyUrl = 'https://' . $_SERVER['HTTP_HOST'] . '/api/callback/wechatCallback';
                    //设置参数
                    $options = Pay::setDriver('WeChat')
                        ->basic('购买商品', $info->sn, $info->real_amount, $notifyUrl)
                        ->setOpenId($user->openid)
                        ->create('JSAPI');
                    return ['code' => 1, 'msg' => '微信支付', 'data' => $options];
                case "wechat_integral":
                    if (md5($param['pay_password']) != $user->pay_password) {
                        return ['code' => -1, 'msg' => '支付密码错误'];
                    }
                    if ($user->assets->integral < $info->integral) {
                        return ['code' => -1, 'msg' => '余额不足'];
                    }
                    $notifyUrl = 'https://' . $_SERVER['HTTP_HOST'] . '/api/callback/wechatIntegral';
                    //设置参数
                    $options = Pay::setDriver('WeChat')
                        ->basic('购买商品', $info->sn, $info->cash, $notifyUrl)
                        ->setOpenId($user->openid)
                        ->create('JSAPI');
                    return ['code' => 1, 'msg' => '组合支付', 'data' => $options];
                default:
                    return ['code' => -1, 'msg' => '支付方式错误！'];
            }

        } catch (\Exception $e) {
            return ['code' => -1, 'msg' => $e->getMessage()];
        }
    }

    public static function operations($info, $user, $account): array
    {
        parent::startTrans();
        try {
            $info->pay_way = $account;
            $info->pay_state = 2;
            $info->pay_time = time();
            if($info->getData('type')==1)
            {
                $info->status = 4;
                $info->finish_time = time();
            }else{
                $info->status = 2;
            }
            $info->save();
            if($account=='wechat_integral')
            {
                Target::Account()->basics($user->id, 'integral', $info->integral, '购买商品', '-')
                    ->createNormal($info->id);
            }
            if (!in_array($account, ['wechat', 'alipay','wechat_integral'])) {
                Target::Account()->basics($user->id, $account, $info->real_amount, '购买商品', '-')
                    ->createNormal($info->id);
            }
            //根据分区不同，处理不同逻辑
//            switch ($info->order_type) {
//                case 1:
//                    break;
//                default:
//                    break;
//            }
            //统计收入，则需使用
//            Event::trigger('Statistics', ['key' => 'income_' . $info->order_type, 'value' => $info->real_amount]);
            parent::commit();
            return ['code' => 1, 'msg' => '支付成功'];
        } catch (\Exception $e) {
            parent::rollback();
            return ['code' => -1, 'msg' => $e->getMessage()];
        }
    }

    /**
     * @param $param
     * @param $user
     * @return array
     * 原点 2022年1月8日16:43:09 订单相关操作
     */
    public static function edit($param, $user): array
    {
        parent::startTrans();
        try {
            $info = parent::where(['id' => $param['id'], 'uid' => $user->id])->find();
            if (empty($info)) {
                return ['code' => -1, 'msg' => '订单不存在'];
            }
            switch ($param['type']) {
                case 'clear': //取消订单
                    if ($info->getData('status') != 1 || $info->pay_state) {
                        return ['code' => -1, 'msg' => '订单已支付，无法取消'];
                    }
                    $info->delete_time = time();
                    $info->status = 7;
                    $info->cancel_time = time();
                    $info->save();
                    parent::commit();
                    return ['code' => 1, 'msg' => '订单已取消'];
                case 'refund': //申请退货
                    if ($info->getData('status') == 5) {
                        return ['code' => -1, 'msg' => '订单已申请'];
                    }
                    $info->status = 5;
                    $info->refund_time = time();
                    $info->reason = $param['reason'];
                    $info->illustrate = $param['illustrate'];
                    $info->refund_img = $param['refund_img'];
                    $info->save();
                    parent::commit();
                    return ['code' => 1, 'msg' => '已申请退款'];
                case "receipt": //确认收货
                    if ($info->getData('status') != 3) {
                        return ['code' => -1, 'msg' => '此订单无需收货'];
                    }
                    self::receipt($info);

                    parent::commit();
                    return ['code' => 1, 'msg' => '已确认收货'];
                default:
                    return ['code' => -1, 'msg' => '加载失败'];

            }
        } catch (\Exception $e) {
            parent::rollback();
            return ['code' => -1, 'msg' => $e->getMessage()];
        }
    }

    /**
     * 订单收货
     * @param $order
     * @param false $is_auto
     * @return array|bool
     */
    public static function receipt($order, $is_auto = false)
    {
        $order->status = 4;
        $order->receipt_time = time();
        $order->finish_time = time();
        if ($is_auto) $order->auto_receipt_time = time();
        $order->save();
        return true;
    }

    /**
     * 自动收货【定时任务】
     * @return array
     */
    public static function autoReceipt(): array
    {
        try {
            $time = time() + Config::where('name', 'task_order_receipt')->value('value');//临时设置发货后5分钟自动收货，上线后改为1296000（15天）
            self::where(['status' => 3])->where('post_time', '>', 0)->where('post_time', '<', $time)->select()->each(function ($item) {
                Db::transaction(function () use ($item) {
                    self::receipt($item, true);
                });
            });
            return ['code' => 1, 'msg' => '自动收货成功'];
        } catch (\Exception $e) {
            return ['code' => -1, 'msg' => $e->getMessage()];
        }
    }

}
